진입 횟수가 매우*매우 많은 파이썬 함수 내부에서,
비트 플래깅용 중형(~수십킬로) numpy 배열을 만들어 쓴다는 가정이다.
numpy는 매번 malloc, free를 수행하며 대부분은 힙에서, 경우에 따라 mmap에서 가져다 쓴다. 느리다.
그 배열을 전역으로 이동하면 이 부분은 해소된다. 전역에서 한 번 선언하고 함수내에서는 청소만 하면 된다.
numpy 배열을 전역에서 선언한다고 해도 bss 로 가지는 않는다. 파이썬과 numpy가 그렇다고 한다.
C라면 alloca 로 스택에서 바로 뽑아 쓸 수가 있다. 빠르다.
모던 C++라면 가변 크기 배열을 쓸 수가 있다. alloca와 같다. 빠르다.
물론 스택이 갖는 크기 제한, 버퍼 넘침 위험성은 있다.
그리하여 전역변수로 numpy 배열을 선언한다고 치자.
용도에 맞게 가변화 할 수는 없다. 요구하는 최대 크기를 미리 계산해서 최대 크기로 선언해야 한다. 또한, 크기에 맞춰서 청소를 하거나, 탐색을 하기 위해 현재 사용 중인 크기 관리도 수반한다.
멀티프로세싱이 들어왔다.
COW가 발생할 때 복제를 수반한다. 앞에서 설명한 용도에 비추어 몇 번 발생하지 않는 비용이다. 매 함수 턴 마다 발생하지는 않는다.
멀티쓰레드면 락비용이 발생한다. 락비용이 매번 malloc, free 하는 비용보다 큰 상황이 많을 뿐더러, 거짓 공유 캐시 메롱도 발생하기 쉽다.
이 글을 chatgpt 에게 확인하라 했더니 오만 잔소리를 쏟아낸다. 대충은 맞는듯 하다.